package ar.edu.unrn.lia.service.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.transaction.annotation.Transactional;

import ar.edu.unrn.lia.dao.CuentaDAO;
import ar.edu.unrn.lia.model.Cliente;
import ar.edu.unrn.lia.model.Cuenta;
import ar.edu.unrn.lia.model.Cuenta.Estado;
import ar.edu.unrn.lia.model.Cuenta.Grupo;
import ar.edu.unrn.lia.model.Cuenta.SubGrupo;
import ar.edu.unrn.lia.service.CuentaService;
import ar.edu.unrn.lia.service.exception.BusinessException;
import ar.edu.unrn.lia.util.MensajesAplicacion;

@Named("cuentaService")
public class CuentaServiceImpl implements CuentaService, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1514551735989712151L;

	static final String CUENTA_CAJA_CODIGO = MensajesAplicacion
			.getString("application.cuentacaja");

	static final String CUENTA_RENTA_CODIGO = MensajesAplicacion
			.getString("application.cuentarenta");

	@Inject
	CuentaDAO entityDAO;

	public CuentaDAO getEntityDAO() {
		return entityDAO;
	}

	@Transactional(readOnly = true)
	public Long getCount(Map<String, String> filters) {
		return getEntityDAO().count(
				getEntityDAO().getSearchPredicates(getEntityDAO().rootCount(),
						filters));
	}

	@Transactional(readOnly = true)
	public List<Cuenta> getList(Integer page, Integer pagesize,
			Map<String, String> filters, String sortField, Boolean asc) {
		return getEntityDAO().listwithPag(
				getEntityDAO().getSearchPredicates(getEntityDAO().rootCount(),
						filters), page, pagesize, sortField, asc);
	}

	@Override
	public void crearCuenta(Cliente cli) {
		Cuenta cuenta = new Cuenta();
		cuenta.setCliente(cli);
		// TODO: Estado de las cuentas???
		cuenta.setEstado(Estado.SALDADA);
		cuenta.setImputable(true);
		cuenta.setNombre(cli.getApellido() + " " + cli.getNombre()
				+ " - CUENTA");
		cuenta.setSaldo(0.0);

		cuenta.setGrupo(Grupo.ACTIVO);
		cuenta.setSubGrupo(SubGrupo.CLIENTES);

		Integer num = entityDAO.buscarUltimoCodDeCuenta(cuenta.getGrupo(),
				cuenta.getSubGrupo());

		cuenta.setNumero(num + 1);
		cuenta.establecerCodigo();

		cli.setCuenta(cuenta);

	}

	@Transactional
	public void save(Cuenta entity) {

		getEntityDAO().create(entity);
	}

	@Transactional
	public void delete(Cuenta entity) {
		getEntityDAO().delete(entity);
	}

	@Transactional
	public void update(Cuenta entity) {
		getEntityDAO().update(entity);
	}

	public Cuenta getEntityById(Long id) {
		return getEntityDAO().read(id);
	}

	public List<Cuenta> getAll() {
		return getEntityDAO().findAll();
	}

	public List<Cuenta> findByQuery(String query, String propertyFilter,
			String orderDirection) {
		return getEntityDAO()
				.findByQuery(query, propertyFilter, orderDirection);
	}

	public Cuenta obtenerCuentaCaja() throws BusinessException {
		try {
			return getEntityDAO().buscarCuentaPorCodigo(CUENTA_CAJA_CODIGO);
		} catch (Exception e) {
			throw new BusinessException("No existe la cuenta Caja.");
		}

	}
	
	public Cuenta obtenerCuentaRenta() throws BusinessException {
		try {
			return getEntityDAO().buscarCuentaPorCodigo(CUENTA_CAJA_CODIGO);
		} catch (Exception e) {
			throw new BusinessException("No existe la cuenta Caja.");
		}

	}
	
	public Cuenta obtenerCuentaRentas() throws BusinessException {
		try {
			return getEntityDAO().buscarCuentaPorCodigo(CUENTA_RENTA_CODIGO);
		} catch (Exception e) {
			throw new BusinessException("No existe la cuenta Rentas.");
		}

	}

	@Transactional(readOnly = true)
	public List<Cuenta> buscarCuentaConDeuda()
	{
		return getEntityDAO().buscarCuentaPorEstado(Estado.SALDO_DEUDOR);
	}
	@Transactional(readOnly = true)
	public List<Cuenta> buscarCuentaAcredor()
	{
		return getEntityDAO().buscarCuentaPorEstado(Estado.SALDO_ACREEDOR);
	}

}